package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"strings"
	"syscall"

	"github.com/pion/rtp"
	"gogs.smarteye.com/servere/gobvrtp"
	"gogs.smarteye.com/servere/gobvrtp/track"
	"gogs.smarteye.com/servere/gobvrtp/track_formats"
)

func main() {

	var (
		tfkURL    = "127.0.0.1:9782"
		discoAddr = "127.0.0.1:9784"

		AppID  = "S8eKX5tXo6344O8ZOOIhbyhe"
		AppKey = "Z49tYAuL0rnTQeuPf5nIjbHMLaRCtUBwdYYeIg"

		puId      = "UA_27423133" //"UA_27423133"
		channelId = 0
	)

	if false {
		tfkURL = "192.168.88.11:9782"
		discoAddr = "192.168.88.11:9784"

		AppID = "L4Y6x6IVzui2iWYppQXXmtgL"
		AppKey = "ke4RllDdN6cfX7B9qcfJC0AeDV9v8gfxLayI0w"
	}
	_ = puId
	_ = channelId

	objectDialog := NewClientDialog(tfkURL, discoAddr, AppID, AppKey, "bvrtc")

	_ = objectDialog

	c := gobvrtp.NewClient() // 设置传输协议, 默认udp

	var (
		fpVideo *os.File
		fpAudio *os.File
	)

	c.Session().SetOnNewTrackFunc(func(t track.Track) {
		log.Printf("新流 %v %v %v", t.Codec(), t.Direction(), t.MarshalFormat().String())

		if t.Codec().MediaType().Video() {
			fpVideo, _ = os.Create("out." + strings.ToLower(t.Codec().String()))
		} else if t.Codec().MediaType().Audio() {
			fpAudio, _ = os.Create("out." + strings.ToLower(t.Codec().String()))
		}
	})
	c.Session().SetOnRTPFunc(
		func(t track.Track, packet *rtp.Packet) {
			t.Codec()
			t.SSRC()
			t.Direction()
			_ = packet.SequenceNumber
			// 接收到 rtp 数据
		},
	)
	c.Session().SetOnLossRTPFunc(
		func(t track.Track, sequenceNumber uint16, diff int) {
			// 丢包
			log.Println(diff)
		},
	)
	c.Session().SetOnFrameFunc(
		func(t track.Track, frame *track.Frame) {
			// 收到解包的数据 NALUs
			log.Printf("[%v:%v] pts: %10v %v", frame.Codec, frame.Codec.MediaType(), frame.PTS, frame.Data[:5])

			var fp *os.File
			switch frame.Codec.MediaType() {
			case track.MediaTypeVideo:
				fp = fpVideo
			case track.MediaTypeAudio:
				fp = fpAudio
			}

			if fp != nil {
				_, _ = fp.Write(frame.Data)
			}
		},
	)

	video := track_formats.NewH264Track()
	audio := track_formats.NewG726Track()

	c.Session().AddReceiveTrack(video, audio)

	log.Println("打开中...")
	_ = c.Open(puId, channelId, objectDialog) // 打开成功或失败

	go func() {
		ctx, _ := signal.NotifyContext(context.TODO(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
		<-ctx.Done()
		_ = c.Close()
	}()

	_ = c.Wait()
}
